package com.flyduck.mall.oms.admin.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.flyduck.mall.common.mybatis.utils.PageUtils;
import com.flyduck.mall.oms.admin.vo.*;
import com.flyduck.mall.oms.manager.OmsOrderManager;
import com.flyduck.mall.oms.mapper.OmsOrderMapper;
import com.flyduck.mall.oms.mapper.OmsRefundMapper;

import com.flyduck.mall.common.core.utils.BeanUtils;
import com.flyduck.mall.ums.api.RemoteUserService;
import com.flyduck.mall.ums.api.vo.RemoteUserRespVO;
import com.flyduck.ss.common.core.exception.ServiceException;
import com.flyduck.ss.common.core.utils.StringUtils;
import com.flyduck.mall.oms.api.constant.OrderConstant;
import com.flyduck.mall.oms.admin.service.AdminOrderService;
import com.flyduck.mall.oms.domain.OmsOrder;
import com.flyduck.mall.oms.domain.OmsOrderItem;
import com.flyduck.mall.oms.domain.OmsRefund;
import com.flyduck.mall.oms.mapper.OmsOrderItemMapper;
import com.flyduck.mall.oms.utils.KdApiSearchUtils;
import com.flyduck.ss.common.satoken.utils.LoginHelper;
import com.flyduck.ss.system.api.model.LoginUser;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * AdminOrderServiceImpl
 * </p>
 *
 * @author flyduck
 * @since 2024-06-11
 */
@Service
public class AdminOrderServiceImpl implements AdminOrderService {

    @Resource
    private OmsOrderMapper omsOrderMapper;
    @Resource
    private OmsOrderItemMapper omsOrderItemMapper;
    @Resource
    private OmsRefundMapper omsRefundMapper;
    @Resource
    private OmsOrderManager omsOrderManager;
    @DubboReference
    private RemoteUserService remoteUserService;

    @Override
    public Page<AdminOrderRespVO> getOrderPage(Page page, AdminOrderQueryReqVO adminOrderQueryReqVO) {
        Page<OmsOrder> appAdPage = omsOrderMapper.selectPage(page,
                new LambdaQueryWrapper<OmsOrder>()
                        .eq(StringUtils.isNotBlank(adminOrderQueryReqVO.getSn()), OmsOrder::getSn, adminOrderQueryReqVO.getSn())
                        .eq(ObjectUtil.isNotNull(adminOrderQueryReqVO.getOrderStatus()), OmsOrder::getOrderStatus, adminOrderQueryReqVO.getOrderStatus())
                        .orderByDesc(OmsOrder::getCreateTime)
        );

        return PageUtils.convert(appAdPage, AdminOrderRespVO.class);
    }

    @Override
    public List<AdminDictRespVO> getOrderStatusList() {
        List<AdminDictRespVO> adminDictRespVOList = new ArrayList<>();
        for (OrderConstant.OrderStatus orderStatus : OrderConstant.OrderStatus.values()) {
            AdminDictRespVO adminDictRespVO = new AdminDictRespVO();
            adminDictRespVO.setKey(orderStatus.getCode());
            adminDictRespVO.setValue(orderStatus.getDescription());
            adminDictRespVOList.add(adminDictRespVO);
        }
        return adminDictRespVOList;
    }

    @Override
    public AdminOrderDetailsRespVO getOrderDetailsById(Long id) {
        //订单基本信息
        OmsOrder omsOrder = omsOrderMapper.selectById(id);
        if(omsOrder == null){
            throw new ServiceException("该订单不存在");
        }
        AdminOrderDetailsRespVO adminOrderDetailsRespVO = BeanUtils.toBean(omsOrder, AdminOrderDetailsRespVO.class);

        //订单项列表
        List<OmsOrderItem> omsOrderItemList = omsOrderItemMapper.getAppOrderItemListByOrderId(id);
        List<AdminOrderDetailsRespVO.OmsOrderItemVO> appOrderItemVOList = BeanUtils.toBeanList(omsOrderItemList, AdminOrderDetailsRespVO.OmsOrderItemVO.class);
        adminOrderDetailsRespVO.setOrderItems(appOrderItemVOList);

        //订单用户信息
        RemoteUserRespVO remoteUserRespVO = remoteUserService.getUserById(omsOrder.getUserId());
        adminOrderDetailsRespVO.setUsername(remoteUserRespVO.getUsername());
        adminOrderDetailsRespVO.setUserAvatar(remoteUserRespVO.getAvatar());

        //退款信息
        OmsRefund omsRefund = omsRefundMapper.selectOne(
                new LambdaQueryWrapper<OmsRefund>()
                        .eq(OmsRefund::getOrderId, id)
        );
        AdminOrderDetailsRespVO.OmsRefundVO appRefundVO = BeanUtils.toBean(omsRefund, AdminOrderDetailsRespVO.OmsRefundVO.class);
        adminOrderDetailsRespVO.setAppRefund(appRefundVO);
        return adminOrderDetailsRespVO;
    }

    @Override
    public void orderDelivery(AdminOrderDeliveryReqVO adminOrderDeliveryReqVO) {
        OmsOrder omsOrder = omsOrderMapper.selectById(adminOrderDeliveryReqVO.getId());
        if (omsOrder == null) {
            throw new ServiceException("该订单不存在");
        }

        if(OrderConstant.OrderStatus.PENDING_DELIVERY.getCode() != omsOrder.getOrderStatus()){
            throw new ServiceException("该订单状态不允许发货");
        }

        if(StringUtils.isBlank(adminOrderDeliveryReqVO.getDeliveryCompany()) || StringUtils.isBlank(adminOrderDeliveryReqVO.getDeliverySn())){
            throw new ServiceException("参数异常");
        }

        omsOrder.setDeliveryCompany(adminOrderDeliveryReqVO.getDeliveryCompany());
        omsOrder.setDeliverySn(adminOrderDeliveryReqVO.getDeliverySn());
        omsOrder.setDeliveryTime(new Date());
        omsOrder.setOrderStatus(OrderConstant.OrderStatus.PENDING_RECEIPT.getCode());
        omsOrder.setUpdateTime(new Date());

        //记录发货人
        omsOrder.setAdminNote("管理员：" + StpUtil.getLoginIdAsLong() + "发货：" + omsOrder.getAdminNote());

        omsOrderMapper.updateById(omsOrder);
    }

    @Override
    public List<AdminDeliveryTraceRespVO> getDeliveryTraceListById(Long id) throws Exception {
        OmsOrder omsOrder = omsOrderMapper.selectById(id);

        String deliveryInfo = new KdApiSearchUtils().getDelivery(omsOrder.getDeliveryCompany(), omsOrder.getDeliverySn());

        JSONArray traces = JSONUtil.parseObj(deliveryInfo).getJSONArray("Traces");
        return traces.stream()
                .map(trace -> {
                    JSONObject jsonObject = JSONUtil.parseObj(trace);
                    AdminDeliveryTraceRespVO adminDeliveryTraceRespVO = new AdminDeliveryTraceRespVO();
                    adminDeliveryTraceRespVO.setAcceptTime(jsonObject.getStr("AcceptTime"));
                    adminDeliveryTraceRespVO.setAcceptStation(jsonObject.getStr("AcceptStation"));
                    adminDeliveryTraceRespVO.setRemark(jsonObject.getStr("Remark"));

                    return adminDeliveryTraceRespVO;
                }).collect(Collectors.toList());
    }

    @Override
    public void closeOrder(AdminOrderCloseReqVO adminOrderDeliveryReqVO) {
        omsOrderManager.closeOrder(adminOrderDeliveryReqVO.getId(),adminOrderDeliveryReqVO.getAdminNote(),StpUtil.getLoginIdAsLong());
    }
}
